package cn.xydpeng.springframework.context.support;

import cn.xydpeng.springframework.beans.BeansException;
import cn.xydpeng.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import cn.xydpeng.springframework.beans.factory.support.DefaultListableBeanFactory;
import cn.xydpeng.springframework.context.ApplicationContext;
import cn.xydpeng.springframework.lang.Nullable;

import java.io.IOException;

/**
 * @author xydpeng
 * @version v1.0
 * @date: 2022/10/17
 * @description:
 */
public abstract class AbstractRefreshableApplicationContext extends AbstractApplicationContext {
    /**
     * Bean factory for this context.
     */
    @Nullable
    private volatile DefaultListableBeanFactory beanFactory;

    @Nullable
    private String[] configLocations;

    public AbstractRefreshableApplicationContext() {
    }

    public AbstractRefreshableApplicationContext(ApplicationContext parent) {
        super(parent);
    }

    @Override
    protected void refreshBeanFactory() {
        try {
            DefaultListableBeanFactory beanFactory = createBeanFactory();
            loadBeanDefinitions(beanFactory);
            this.beanFactory = beanFactory;
        } catch (IOException ex) {
            throw new RuntimeException("I/O error parsing bean definition source");
        }
    }

    @Override
    public ConfigurableListableBeanFactory getBeanFactory() throws IllegalStateException {
        return this.beanFactory;
    }

    protected DefaultListableBeanFactory createBeanFactory() {
        return new DefaultListableBeanFactory();
    }

    protected abstract void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException;

    public String[] getConfigLocations() {
        return configLocations;
    }

    public void setConfigLocations(String[] configLocations) {
        this.configLocations = configLocations;
    }
}
